package com.feijie.thread_demo.LockThread;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @program: thread_demo
 * @description: 使用lock锁对象进行保护线程安全
 * @author: 作者
 * @create: 2022-03-07 14:45
 */
public class ThreadLockSecurity {

    /**
     * 实现Runnable方法主要是为了开启多线程
     */

    static int tickets = 10;

    class SellTickets implements Runnable{


        /**
         * 创建lock锁对象，lock的锁对象主要是当前ReentrantLock对象
         */
        Lock lock = new ReentrantLock();


        @Override
        public void run() {
            // Lock锁机制
            while(tickets > 0) {

                try {
                    lock.lock();
                    System.out.println("lock "+ tickets +"==>"+lock.hashCode());

                    if (tickets <= 0) {

                        return;
                    }

                    System.out.println(Thread.currentThread().getName()+"--->售出第：  "+tickets+" 票");
                    tickets--;
                } catch (Exception e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }finally {

                    lock.unlock();
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

            if (tickets <= 0) {

                System.out.println(Thread.currentThread().getName()+"--->售票结束！");
            }

        }
    }


    public static void main(String[] args) {

        /**
         * 当线程中的实例对象不同时，lock锁的对象也不同则无法做到线程安全
         */

        SellTickets sell1 = new ThreadLockSecurity().new SellTickets();
        SellTickets sell2 = new ThreadLockSecurity().new SellTickets();
        System.out.println("sell1==>"+sell1.hashCode());
        System.out.println("sell2==>"+sell2.hashCode());

        Thread thread1 = new Thread(sell1, "1号窗口");
        Thread thread2 = new Thread(sell1, "2号窗口");
        Thread thread3 = new Thread(sell2, "3号窗口");
        Thread thread4 = new Thread(sell2, "4号窗口");

        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();


    }

}
